package com.timeshare.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.timeshare.dto.AppointmentRequest;
import com.timeshare.dto.AppointmentVO;
import com.timeshare.entity.Appointment;
import com.timeshare.entity.Skill;
import com.timeshare.entity.User;
import com.timeshare.mapper.AppointmentMapper;
import com.timeshare.mapper.SkillMapper;
import com.timeshare.mapper.UserMapper;
import com.timeshare.service.AppointmentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 预约服务实现
 */
@Service
public class AppointmentServiceImpl extends ServiceImpl<AppointmentMapper, Appointment> implements AppointmentService {
    
    private final SkillMapper skillMapper;
    private final UserMapper userMapper;
    
    private static final Map<Integer, String> STATUS_MAP = new HashMap<>();
    static {
        STATUS_MAP.put(0, "待确认");
        STATUS_MAP.put(1, "已确认");
        STATUS_MAP.put(2, "进行中");
        STATUS_MAP.put(3, "已完成");
        STATUS_MAP.put(4, "已取消");
        STATUS_MAP.put(5, "已拒绝");
    }
    
    public AppointmentServiceImpl(SkillMapper skillMapper, UserMapper userMapper) {
        this.skillMapper = skillMapper;
        this.userMapper = userMapper;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createAppointment(Long userId, AppointmentRequest request) {
        // 查询技能信息
        Skill skill = skillMapper.selectById(request.getSkillId());
        if (skill == null) {
            throw new RuntimeException("技能不存在");
        }
        
        // 不能预约自己的技能
        if (skill.getUserId().equals(userId)) {
            throw new RuntimeException("不能预约自己的技能");
        }
        
        // 创建预约
        Appointment appointment = new Appointment();
        appointment.setSkillId(request.getSkillId());
        appointment.setRequesterId(userId);
        appointment.setProviderId(skill.getUserId());
        appointment.setAppointmentTime(request.getAppointmentTime());
        appointment.setDuration(request.getDuration() != null ? request.getDuration() : 60);
        appointment.setNote(request.getNote());
        appointment.setStatus(0); // 待确认
        
        this.save(appointment);
        
        // 更新技能预约次数
        skill.setAppointmentCount(skill.getAppointmentCount() + 1);
        skillMapper.updateById(skill);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmAppointment(Long userId, Long appointmentId) {
        Appointment appointment = this.getById(appointmentId);
        if (appointment == null) {
            throw new RuntimeException("预约不存在");
        }
        
        // 只有提供者可以确认
        if (!appointment.getProviderId().equals(userId)) {
            throw new RuntimeException("无权操作");
        }
        
        if (appointment.getStatus() != 0) {
            throw new RuntimeException("当前状态不允许确认");
        }
        
        appointment.setStatus(1); // 已确认
        this.updateById(appointment);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void rejectAppointment(Long userId, Long appointmentId) {
        Appointment appointment = this.getById(appointmentId);
        if (appointment == null) {
            throw new RuntimeException("预约不存在");
        }
        
        // 只有提供者可以拒绝
        if (!appointment.getProviderId().equals(userId)) {
            throw new RuntimeException("无权操作");
        }
        
        if (appointment.getStatus() != 0) {
            throw new RuntimeException("当前状态不允许拒绝");
        }
        
        appointment.setStatus(5); // 已拒绝
        this.updateById(appointment);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelAppointment(Long userId, Long appointmentId) {
        Appointment appointment = this.getById(appointmentId);
        if (appointment == null) {
            throw new RuntimeException("预约不存在");
        }
        
        // 只有发起者可以取消
        if (!appointment.getRequesterId().equals(userId)) {
            throw new RuntimeException("无权操作");
        }
        
        if (appointment.getStatus() >= 3) {
            throw new RuntimeException("当前状态不允许取消");
        }
        
        appointment.setStatus(4); // 已取消
        this.updateById(appointment);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startAppointment(Long userId, Long appointmentId) {
        Appointment appointment = this.getById(appointmentId);
        if (appointment == null) {
            throw new RuntimeException("预约不存在");
        }
        
        // 双方都可以开始
        if (!appointment.getRequesterId().equals(userId) && !appointment.getProviderId().equals(userId)) {
            throw new RuntimeException("无权操作");
        }
        
        if (appointment.getStatus() != 1) {
            throw new RuntimeException("当前状态不允许开始");
        }
        
        appointment.setStatus(2); // 进行中
        this.updateById(appointment);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeAppointment(Long userId, Long appointmentId) {
        Appointment appointment = this.getById(appointmentId);
        if (appointment == null) {
            throw new RuntimeException("预约不存在");
        }
        
        // 双方都可以完成
        if (!appointment.getRequesterId().equals(userId) && !appointment.getProviderId().equals(userId)) {
            throw new RuntimeException("无权操作");
        }
        
        if (appointment.getStatus() != 2) {
            throw new RuntimeException("当前状态不允许完成");
        }
        
        appointment.setStatus(3); // 已完成
        appointment.setCompleteTime(LocalDateTime.now());
        this.updateById(appointment);
        
        // 增加双方积分和信誉分
        User requester = userMapper.selectById(appointment.getRequesterId());
        User provider = userMapper.selectById(appointment.getProviderId());
        
        if (requester != null) {
            requester.setPoints(requester.getPoints() + 10);
            userMapper.updateById(requester);
        }
        
        if (provider != null) {
            provider.setPoints(provider.getPoints() + 10);
            userMapper.updateById(provider);
        }
    }
    
    @Override
    public Page<AppointmentVO> getMyRequests(Long userId, Integer page, Integer size) {
        Page<Appointment> appointmentPage = new Page<>(page, size);
        LambdaQueryWrapper<Appointment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Appointment::getRequesterId, userId)
               .orderByDesc(Appointment::getCreateTime);
        this.page(appointmentPage, wrapper);
        
        return convertToVOPage(appointmentPage);
    }
    
    @Override
    public Page<AppointmentVO> getMyReceived(Long userId, Integer page, Integer size) {
        Page<Appointment> appointmentPage = new Page<>(page, size);
        LambdaQueryWrapper<Appointment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Appointment::getProviderId, userId)
               .orderByDesc(Appointment::getCreateTime);
        this.page(appointmentPage, wrapper);
        
        return convertToVOPage(appointmentPage);
    }
    
    @Override
    public AppointmentVO getAppointmentDetail(Long appointmentId) {
        Appointment appointment = this.getById(appointmentId);
        if (appointment == null) {
            throw new RuntimeException("预约不存在");
        }
        
        return convertToVO(appointment);
    }
    
    /**
     * 转换为VO对象
     */
    private AppointmentVO convertToVO(Appointment appointment) {
        AppointmentVO vo = new AppointmentVO();
        BeanUtil.copyProperties(appointment, vo);
        
        // 查询技能信息
        Skill skill = skillMapper.selectById(appointment.getSkillId());
        if (skill != null) {
            vo.setSkillTitle(skill.getTitle());
        }
        
        // 查询发起者信息
        User requester = userMapper.selectById(appointment.getRequesterId());
        if (requester != null) {
            vo.setRequesterNickname(requester.getNickname());
            vo.setRequesterAvatar(requester.getAvatar());
        }
        
        // 查询提供者信息
        User provider = userMapper.selectById(appointment.getProviderId());
        if (provider != null) {
            vo.setProviderNickname(provider.getNickname());
            vo.setProviderAvatar(provider.getAvatar());
        }
        
        // 设置状态文本
        vo.setStatusText(STATUS_MAP.get(appointment.getStatus()));
        
        return vo;
    }
    
    /**
     * 转换为VO分页对象
     */
    private Page<AppointmentVO> convertToVOPage(Page<Appointment> appointmentPage) {
        Page<AppointmentVO> voPage = new Page<>(appointmentPage.getCurrent(), appointmentPage.getSize(), appointmentPage.getTotal());
        List<AppointmentVO> voList = appointmentPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        voPage.setRecords(voList);
        return voPage;
    }
}

